package handler

import (
	"gozeroStandalone/internal/svc"
	"net/http"

	"github.com/zeromicro/go-zero/rest/httpx"
	"google.golang.org/grpc/status"
)

/*
 +----------------------------------------------------------------------
 + Title        : BaseHandler
 + Author       : huwl
 + Version      : 1.0.0
 + Initial-Time : 2025-08-08
 + Last-time    : 这个文件最后修改的时间 + 修改人的名称
 + Desc         : 基础处理器
 +----------------------------------------------------------------------
*/

type BaseHandler struct {
	SvcCtx *svc.ServiceContext
}

// 输出参数结构体
type Params struct {
	StatusCode int
	Code       int
	Data       interface{}
	Message    string
}

// 处理接口
type Handler interface {
	parse(params *Params)
}

// 处理函数
type HandleFunc func(*Params)

// 解析
func (f HandleFunc) parse(params *Params) {
	f(params)
}

/**
 * 设置数据,针对不同默认参数设置闭包函数
 * 这里比较关键，闭包函数=函数+运行环境（可以引用外部函数的变量）
 *
 * @param statusCode int ---------------------------必传
 * @return HandleFunc
 * @author huwl
 */
func (control *BaseHandler) WithStatusCode(statusCode int) HandleFunc {
	return func(params *Params) {
		params.StatusCode = statusCode
	}
}

/**
 * 设置数据,针对不同默认参数设置闭包函数
 * 这里比较关键，闭包函数=函数+运行环境（可以引用外部函数的变量）
 *
 * @param code int ---------------------------------必传
 * @return HandleFunc
 * @author huwl
 */
func (control *BaseHandler) WithCode(code int) HandleFunc {
	return func(params *Params) {
		params.Code = code
	}
}

/**
 * 设置数据,针对不同默认参数设置闭包函数
 * 这里比较关键，闭包函数=函数+运行环境（可以引用外部函数的变量）
 *
 * @param data interface ---------------------------必传
 * @return HandleFunc
 * @author huwl
 */
func (control *BaseHandler) WithData(data interface{}) HandleFunc {
	return func(params *Params) {
		params.Data = data
	}
}

/**
 * 设置信息,针对不同默认参数设置闭包函数
 * 这里比较关键，闭包函数=函数+运行环境（可以引用外部函数的变量）
 *
 * @param message string ---------------------------必传
 * @return HandleFunc
 * @author huwl
 */
func (control *BaseHandler) WithMessage(message string) HandleFunc {
	return func(params *Params) {
		params.Message = message
	}
}

/**
 * 从gRPC错误中提取纯净消息,针对不同默认参数设置闭包函数
 * 这里比较关键，闭包函数=函数+运行环境（可以引用外部函数的变量）
 *
 * @param message string ---------------------------必传
 * @return HandleFunc
 * @author huwl
 */
func (control *BaseHandler) WithGrpcError(err error) HandleFunc {
	return func(params *Params) {
		if st, ok := status.FromError(err); ok {
			// 只返回状态中的消息部分
			params.Message = st.Message()
		} else {
			// 如果不是gRPC错误，返回原始错误
			params.Message = err.Error()
		}
	}
}

/**
 * 成功
 *
 * @param ctx *gin.Context -------------------------必传
 * @param params []Handler -------------------------非必传
 * @return Json
 * @author huwl
 */
func (control *BaseHandler) BaseSuccess(r *http.Request, w http.ResponseWriter, params ...Handler) {
	result := &Params{
		StatusCode: 200,
		Code:       200,
		Data:       nil,
		Message:    "",
	}

	for _, param := range params {
		param.parse(result)
	}
	httpx.OkJsonCtx(r.Context(), w, map[string]interface{}{
		"status_code": result.StatusCode,
		"code":        result.Code,
		"data":        result.Data,
		"message":     result.Message,
	})
}

/**
 * 错误
 *
 * @param ctx *gin.Context -------------------------必传
 * @param params []Handler -------------------------非必传
 * @return Json
 * @author huwl
 */
func (control *BaseHandler) BaseError(r *http.Request, w http.ResponseWriter, params ...Handler) {
	result := &Params{
		StatusCode: 400,
		Code:       400,
		Data:       nil,
		Message:    "",
	}

	for _, param := range params {
		param.parse(result)
	}
	httpx.OkJsonCtx(r.Context(), w, map[string]interface{}{
		"status_code": result.StatusCode,
		"code":        result.Code,
		"data":        result.Data,
		"message":     result.Message,
	})
}
